home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / CODECS.ZIP / codecs / english / dcodrle4.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-13  |  5.6 KB  |  135 lines

  1. /* File: dcodrle4.c
  2.    Author: David Bourgin
  3.    Creation date: 1/2/94
  4.    Last update: 22/5/94
  5.    Purpose: Example of RLE type 4 decoding with a file source to decompress.
  6. */
  7.  
  8. #include <stdio.h>
  9. /* For routines printf,fgetc,fread and fwrite */
  10. #include <memory.h>
  11. /* For routines memset,memcpy */
  12. #include <stdlib.h>
  13. /* For routine exit */
  14.  
  15. /* Error codes sent to the caller */
  16. #define NO_ERROR      0
  17. #define BAD_FILE_NAME 1
  18. #define BAD_ARGUMENT  2
  19.  
  20. /* Useful constants */
  21. #define FALSE 0
  22. #define TRUE  1
  23.  
  24. /* Global variables */
  25. FILE *source_file,*dest_file;
  26.  
  27.                              /* Being that fgetc=EOF only after an access
  28.                                 then 'byte_stored_status' is 'TRUE' if a byte has been stored by 'fgetc'
  29.                                 or 'FALSE' if there's no valid byte not already read and not handled in 'val_byte_stored' */
  30. int byte_stored_status=FALSE;
  31. int val_byte_stored;
  32.  
  33. /* Pseudo procedures */
  34. #define end_of_data()  (byte_stored_status?FALSE:!(byte_stored_status=((val_byte_stored=fgetc(source_file))!=EOF)))
  35. #define read_byte()  (byte_stored_status?byte_stored_status=FALSE,(unsigned char)val_byte_stored:(unsigned char)fgetc(source_file))
  36. #define read_array(array,nb_to_read)  { if (byte_stored_status)\
  37.                                           { *(array)=(unsigned char)val_byte_stored;\
  38.                                             byte_stored_status=FALSE;\
  39.                                             if ((nb_to_read)>1)\
  40.                                                (void)fread(&((array)[1]),1,(nb_to_read)-1,source_file);\
  41.                                           }\
  42.                                        else (void)fread((array),1,(nb_to_read),source_file);\
  43.                                      }
  44. #define write_array(array,array_size)  ((void)fwrite((array),1,(array_size),dest_file))
  45. #define fill_array(array,nb_to_fill,value)  ((void)memset((array),(value),(nb_to_fill)))
  46. #define block_copy(source,destination,source_size,nb_of_time)  { register unsigned int i, index=0;\
  47.                                                                  for (i=1;i<=(nb_of_time);i++)\
  48.                                                                      { (void)memcpy(&((destination)[index]),(source),(source_size));\
  49.                                                                        index += (source_size);\
  50.                                                                      }\
  51.                                                                }
  52.  
  53. void rle4decoding()
  54. /* Returned parameters: None
  55.    Action: Decompresses with RLE type 4 method all bytes read by the function read_byte
  56.    Erreurs: An input/output error could disturb the running of the program
  57. */
  58. { unsigned char byte_code;
  59.   unsigned int frame_size,frame_nb;
  60.   unsigned char frame[16705];
  61.  
  62.   while (!end_of_data())
  63.         { byte_code=read_byte();
  64.           switch (byte_code & 192)
  65.           { case 0:          /* Frames repetition of 1 byte
  66.                                 Encoding [00xxxxxx|1 byte] */
  67.                    frame_size=(byte_code & 63)+2;
  68.                    fill_array(frame,frame_size,read_byte());
  69.                    break;
  70.             case 64:         /* Frames repetition of less 66 bytes
  71.                                 Encoding [01xxxxxx|xxxxxxxx|1 byte] */
  72.                     frame_size=(((unsigned int)(byte_code & 63)) << 8)+read_byte()+66;
  73.                     fill_array(frame,frame_size,read_byte());
  74.                     break;
  75.             case 128:        /* Frame with several bytes
  76.                                 Encoding [10xxxxxx|yyyyyyyy|n bytes] */
  77.                      frame_size=(byte_code & 63)+2;
  78.                      frame_nb=((unsigned int)read_byte())+2;
  79.                      read_array(frame,frame_size);
  80.                      block_copy(frame,frame+frame_size,frame_size,frame_nb);
  81.                      frame_size *= frame_nb;
  82.                      break;
  83.             case 192:        /* No repetition
  84.                                 Encoding [110xxxxxx|n octets] or [111xxxxxx|yyyyyyyy|n octets] */
  85.                      frame_size=byte_code & 31;
  86.                      if (!(byte_code & 32))
  87.                              /* Non repetition of less 33 bytes [110xxxxxx|n bytes] ? */
  88.                         frame_size++;
  89.                      else frame_size=(frame_size << 8)+read_byte()+33;
  90.                      read_array(frame,frame_size);
  91.                      break;
  92.           }
  93.           write_array(frame,frame_size);
  94.         }
  95. }
  96.  
  97. void aide()
  98. /* Returned parameters: None
  99.    Action: Displays the help of the program and the stop its running
  100.    Erreurs: None
  101. */
  102. { printf("This utility enables you to decompress a file by using RLE type 4 method\n");
  103.   printf("as given in 'La Video et Les Imprimantes sur PC'\n");
  104.   printf("\nUse: dcodrle4 source target\n");
  105.   printf("source: Name of the file to decompress\n");
  106.   printf("target: Name of the restored file\n");
  107. }
  108.  
  109. int main(argc,argv)
  110. /* Returned parameters: Returns an error code (0=None)
  111.    Action: Main procedure
  112.    Erreurs: Detected, handled and an error code is returned, if any
  113. */
  114. int argc;
  115. char *argv[];
  116. { if (argc!=3)
  117.      { aide();
  118.        exit(BAD_ARGUMENT);
  119.      }
  120.   else if ((source_file=fopen(argv[1],"rb"))==NULL)
  121.           { aide();
  122.             exit(BAD_FILE_NAME);
  123.           }
  124.        else if ((dest_file=fopen(argv[2],"wb"))==NULL)
  125.                { aide();
  126.                  exit(BAD_FILE_NAME);
  127.                }
  128.             else { rle4decoding();
  129.                    fclose(source_file);
  130.                    fclose(dest_file);
  131.                  }
  132.   printf("Execution of dcodrle4 completed.\n");
  133.   return (NO_ERROR);
  134. }
  135.